﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SIGEB.Modelo;
using SIGEB.Prototipo.control;
using SIGEB.Modelo.moduloUsuarios;
using SIGEB.Modelo.moduloPerfiles;
using SIGEB.Modelo.moduloGrupo;

namespace SIGEB.Prototipo.Control
{
    public class controlUsuarios
    {
        #region "constructores"

        public controlUsuarios(controlPrincipal cp)
        {
            this.cp = cp;
            datos = this.cp.datos;
        }

        #endregion  

        #region "metodos"

        #region "validacion"

        internal bool camposUsuarioValido(String idUsuario, String cedula, String nombre, String apellido1, String apellido2,
            bool mujer, String password, String domicilio, String email, String telefono, String idGrupo, String permisos)
        {
            if (campoUsuarioValido(idUsuario))
                if (campoCedulaValido(cedula))
                    if (campoNombreValido(nombre))
                        if (campoApellido1Valido(apellido1))
                            if (campoApellido2Valido(apellido2))
                                if (campoDomicilioValido(domicilio))
                                    if (campoEmailValido(email))
                                        if (campoTelefonoValido(telefono))
                                            if (idGrupoValido(idGrupo))
                                                if (permisosValidos(idGrupo, permisos))
                                                    return true;
            return false;
        }

        internal bool idGrupoValido(string idGrupo)
        {
            return Validacion.LongitudCadenaValida(idGrupo, false, 20);
        }

        internal bool permisosValidos(string idGrupo, string permisos)
        {
            tipoPerfil tipoPerf = tipoPerfilByGrupo(idGrupo);
            return tipoPerf.permisoCorrectos(permisos);
        }

        internal void completarDatosUsuario(usuario completar)
        {
            usuario nuevo = cp.datos.usuarios.obtenerusuario(completar.idUsuario);
            if (string.IsNullOrEmpty(completar.permisos) || completar.permisos.Count() != acciones.MAXIMO + 1)
            {
                completar.permisos = nuevo.permisos;
            }
            if (string.IsNullOrEmpty(completar.idGrupo))
            {
                completar.idGrupo = nuevo.idGrupo;
            }
        }

        internal bool idUsuarioValido(string idUsuario)
        {
            return Validacion.LongitudCadenaValida(idUsuario, true, 20);
        }

        internal bool campoUsuarioValido(String idUsuario)
        {
            return Validacion.LongitudCadenaValida(idUsuario, true, 0);
        }

        internal bool campoCedulaValido(String cedula)
        {
            return Validacion.validaCedula(cedula, false);
        }

        internal bool campoNombreValido(String nombre)
        {
            return Validacion.LongitudCadenaValida(nombre,true,0);
        }

        internal bool campoApellido1Valido(String apellido1)
        {
            return Validacion.LongitudCadenaValida(apellido1, true, 0);
        }

        internal bool campoApellido2Valido(String apellido2)
        {
            return Validacion.LongitudCadenaValida(apellido2, false, 0);
        }

        internal bool campoDomicilioValido(String Domicilio)
        {
            return Validacion.LongitudCadenaValida(Domicilio, false, 0);
        }

        internal bool campoEmailValido(String Email)
        {
            return Validacion.validaEmail(Email, false);
        }

        internal bool campoTelefonoValido(String telefono)
        {
            return Validacion.LongitudCadenaValida(telefono, false, 0);
        }

        internal bool existeUsuario(string id)
        {
            return cp.datos.usuarios.obtenerusuario(id) != null;
        }

        #endregion

        internal void registrarUsuario(String idUsuario, String cedula, String nombre, String apellido1, String apellido2,
            bool mujer, String password, String domicilio, String email, String telefono, String idGrupo, String permisos)
        {
            if (!camposUsuarioValido(idUsuario, cedula, nombre, apellido1, apellido2, mujer, password, domicilio, email, telefono,idGrupo,permisos))
            {
                throw new Exception("Uno o más campos del usuario son incorrectos");
            }
            if (!cp.usuarioActualPuede(acciones.USRS_AGREGAR))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            datos.usuarios.agregarusuario(new usuario(idUsuario, cedula, nombre, apellido1, apellido2, mujer, password, domicilio, email, telefono, idGrupo, permisos));

        }

        internal void actualizarCampos(String idUsuario, String cedula, String nombre, String apellido1, String apellido2,
            bool mujer, String password, String domicilio, String email, String telefono, int estado, String idGrupo, String permisos)
        {
            usuario act = cp.datos.usuarios.obtenerusuario(idUsuario);
            if (!cp.usuarioActualPuede(acciones.USER_MODIFICAR_TOD) && !cp.usuarioActualPuede(acciones.USER_MODIFICAR_ACT))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            if (!cp.usuarioActualPuede(acciones.USER_MODIFICAR_TOD) && cp.usuarioActualPuede(acciones.USER_MODIFICAR_ACT) && act.idUsuario != cp.UsuarioActual)
            {
                cp.ExcepcionUsrSinPermisos();
            }
    
            if (String.IsNullOrEmpty(permisos) || !cp.usuarioActualPuede(acciones.PERF_MODIFICAR))
            {
                permisos = act.permisos;
            }
            if (String.IsNullOrEmpty(idGrupo) || (!cp.usuarioActualPuede(acciones.GRUPOS_MODIFICAR_ACTUAL) && act.idUsuario == cp.usuarioActual().idUsuario))
            {
                idGrupo = act.idGrupo;
            }
            if (!camposUsuarioValido(idUsuario, cedula, nombre, apellido1, apellido2, mujer, password, domicilio, email, telefono, idGrupo, permisos))
            {
                throw new Exception("Uno o más campos del usuario son incorrectos");
            }
            datos.usuarios.modificarusuario(idUsuario, new usuario(idUsuario, cedula, nombre, apellido1, apellido2, mujer, password, domicilio, email, telefono, estado,idGrupo, permisos));
        }

        internal void actualizarPassword(String idUsuario, String password)
        {
            if (!campoUsuarioValido(idUsuario))
            {
                throw new Exception("El idUsuario no puede ser vacío");
            }
            datos.usuarios.modificarPassword(idUsuario, password);
        }

        internal void desactivarUsuario(String idUsuario)
        {
            if (!campoUsuarioValido(idUsuario))
            {
                throw new Exception("El idUsuario no puede ser vacío");
            }
            if (!cp.usuarioActualPuede(acciones.USER_MODIFICAR_TOD))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            datos.usuarios.desactivarUsuario(idUsuario);
        }

        internal void eliminarUsuario(String idUsuario)
        {
            if (cp.UsuarioActual == idUsuario)
            {
                throw new Exception("No se puede eliminar el usuario actual");
            }
            if (!idUsuarioValido(idUsuario))
            {
                throw new Exception("El id Usuario no puede ser nulo");
            }
            if (!cp.usuarioActualPuede(acciones.USER_ELIMINAR))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            datos.usuarios.eliminarusuario(idUsuario);
        }

        /// <summary>
        /// Devuelve los usuarios que pertenecen al grupo indicado
        /// </summary>
        /// <param name="idGrupo">El id del grupo quiere sirve de filtro</param>
        /// <returns></returns>
        internal LinkedList<usuario> usuariosGrupo(String idGrupo)
        {
            if (!Validacion.LongitudCadenaValida(idGrupo, true, 0))
            {
                throw new Exception("idGrupo inválido");
            }
            if (!cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            return datos.usuarios.usuariosGrupo(idGrupo);
        } 
        
        internal LinkedList<grupo> obtenerGrupos()
        {
            if (!cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD))
            {
                if (cp.usuarioActualPuede(acciones.GRUPOS_CONSULTAR_ACTUAL))
                {
                    LinkedList<grupo> g = new LinkedList<grupo>();
                    g.AddLast(datos.grupos.obtenergrupo(cp.usuarioActual().idGrupo));
                    return g;
                }
                return null;
            }
            return cp.datos.grupos.obtenergrupos();
        }

        internal LinkedList<tipoUsuario> obtenerTipoUsuarios()
        {
            if (!cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD))
            {
                return null;
            }
            return cp.datos.tiposUsuario.obtenertipoUsuario();
        }

        internal LinkedList<usuario> usuariosMorosos()
        {
            if (!cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD))
            {
                return null;
            }
            LinkedList<usuario> users = datos.usuarios.morosos();
            if (!cp.usuarioActualPuede(acciones.PERF_CONSULTAR_TOD))
            {
                foreach (usuario act in users)
                {
                    act.permisos = "";
                }
            }
            return users;
        }

        internal LinkedList<usuario> todosUsuarios()
        {
            if (!cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD))
            {
                if (cp.usuarioActualPuede(acciones.USER_CONSULTAR_ACT))
                {
                    usuario n = datos.usuarios.obtenerusuario(cp.usuarioActual().idUsuario);
                    if (!cp.usuarioActualPuede(acciones.PERF_CONSULTAR_ACT))
                    {
                        n.permisos = "";
                    }
                    if (!cp.usuarioActualPuede(acciones.GRUPOS_CONSULTAR_ACTUAL))
                    {
                        n.idGrupo = "";
                    }
                    LinkedList<usuario> g = new LinkedList<usuario>();
                    g.AddLast(n);
                    return g;
                }
                else
                {
                    return null;
                }
            }
            LinkedList<usuario> users = datos.usuarios.obtenerTodos();
            if (!cp.usuarioActualPuede(acciones.PERF_CONSULTAR_TOD))
            {
                foreach (usuario act in users)
                {
                    act.permisos = "";
                }
            }
            return users;
        }

        internal usuario obtenerUsuario(String idUsuario)
        {
            if (cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD) || (cp.usuarioActualPuede(acciones.USER_CONSULTAR_ACT) && idUsuario == cp.UsuarioActual))
            {
                usuario user = datos.usuarios.obtenerusuario(idUsuario);
                return user;
            }
            else
            {
                return null;
            }
        }

        internal tipoPerfil tipoPerfilByGrupo(string idGrupo)
        {
            if (idGrupoValido(idGrupo))
            {
                return cp.datos.tipoPerfiles.obtenerTipoPerfilByidGrupo(idGrupo);
            }
            return null;
        }

        internal LinkedList<usuario> usuariosById(LinkedList<usuario> lista, string id)
        {
            LinkedList<usuario> nueva = new LinkedList<usuario>();
            if (lista != null)
            {
                foreach (usuario act in lista)
                {
                    if (act.idUsuario == id)
                    {
                        nueva.AddLast(act);
                        break;
                    }
                }
            }
            return nueva;
        }

        internal bool MatchPassUser(string id, string pass)
        {
            usuario user = cp.datos.usuarios.obtenerusuario(id);
            if (user == null)
            {
                return false;
            }
            return user.password == pass;
        }

        internal LinkedList<usuario> usuariosMultas()
        {
            if (!cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD))
            {
                return null;
            }
            LinkedList<usuario> users = datos.usuarios.conMulta();
            if (!cp.usuarioActualPuede(acciones.PERF_CONSULTAR_TOD))
            {
                foreach (usuario act in users)
                {
                    act.permisos = "";
                }
            }
            return users;
        }

        #endregion

        #region "atributos"

        private controlPrincipal cp;
        private datosAplicacion datos;

        #endregion


    }
}
